//
// Created by 翔 on 2019/5/30.
//

// jni头文件
#include <jni.h>
#include "Hello.h"


// __________________________获取 变量 ——————————————————————————————————————————
// 静态注册  Java_
// 获取 非静态变量
JNIEXPORT jstring JNICALL Java_com_xiang_demo_Hello_getText
        (JNIEnv *env, jobject obj) {
    //  获取Java  类；  反射
    jclass class = (*env)->FindClass(env, "com/xiang/demo/Hello");
    //  获取ID   参数： 1 指针 2类，3 字段名称 4 字段签名(类型) 注意分号
    jfieldID id = (*env)->GetFieldID(env, class, "TAG", "Ljava/lang/String;");
    //  更具字段值 获取字段值
    jstring jobject1 = (*env)->GetObjectField(env, obj, id);
    const char *chars = (*env)->GetStringUTFChars(env, jobject1, 0);
    //   直接返回
    // return (*env)->NewStringUTF(env, "我是 C 测试2 " );
    // 返回  获取Java 成员返回
    return (*env)->NewStringUTF(env, chars);
}


// 静态注册  Java_
// 获取静态变量
JNIEXPORT jfloat JNICALL Java_com_xiang_demo_Hello_getNumber
        (JNIEnv *env, jclass class) {
    // 获取ID  1 指针 2类，3 字段名称 4 字段签名(类型)
    jfieldID id = (*env)->GetStaticFieldID(env, class, "age", "F");
    //  获取字段
    jfloat age = (*env)->GetStaticFloatField(env, class, id);
    return age;


};

// __________________________静态注册 方法——————————————————————————————————————————
 //  获取类
 //  获取方法ID
 //  获取方法

// 静态注册  Java_
// h获取 非静态 方法
JNIEXPORT jstring JNICALL Java_com_xiang_demo_Hello_outPut
        (JNIEnv *env, jobject obj) {
    //  获取Java  类；  反射
    jclass cl = (*env)->FindClass(env, "com/xiang/demo/Hello");
    // 获取方法id    1 指针 2类，3 方法名称 4 方法签名  （）是参数列表  返回类型
    jmethodID methodId = (*env)->GetMethodID(env, cl, "getParameter",
                                             "(Ljava/lang/String;)Ljava/lang/String;");
    jstring txt = (*env)->NewStringUTF(env, "我是参数");
    //  获取Java  获取 非静态 方法
    jstring str = (*env)->CallObjectMethod(env, obj, methodId, txt);
    return str;
}




// 静态注册  Java_
// h获取 静态 方法
JNIEXPORT jfloat JNICALL Java_com_xiang_demo_Hello_outPutStatic
        (JNIEnv *env, jclass cl) {
    // 获取方法id    1 指针 2类，3 方法名称 4 方法签名  （）是参数列表  返回类型
    jmethodID id = (*env)->GetStaticMethodID(env, cl, "getAge", "()F");
    //  获取Java  获取 静态 方法
    jfloat f = (*env)->CallStaticFloatMethod(env, cl, id);
    return f;


};



// __________________________动态注册 方法——————————————————————————

// 步骤
// 1  在Java 层 申明 需要注册的方法
// 2  在c 层  申明 对应的Java 层方法
// 3  申明对应关系 数组
// 4   在  JNI_OnLoad 方法 使用  RegisterNatives 方法注册
//

//



// 申明  对应的 c 层所对应的 Java 层方法
// 1 指针 2  对象 或者  clsaa  其它为参数
jint add(JNIEnv *env, jobject obj, jfloat t1, jfloat t2) {
    return t1 + t2;
}

jint sub(JNIEnv *env, jobject obj, jfloat t1, jfloat t2) {
    return t1 - t2;
}

jdouble mul(JNIEnv *env, jobject obj, jfloat t1, jfloat t2) {
    return t1 * t2;
}

jdouble div(JNIEnv *env, jobject obj, jfloat t1, jfloat t2) {
    return t1 / t2;
}

// 需要动态注册的 方法对应关系集合   多个需要用{} 用逗号隔开
//  格式  { " 需要注册的Java层方法" ，"（参数列表）返回类型" (void *) c对应方法  }
JNINativeMethod getMethods[] = {
        {"add", "(FF)I", (void *) add},
        {"sub", "(FF)I", (void *) sub},
        {"mul", "(FF)D", (void *) mul},
        {"div", "(FF)D", (void *) div}

};

// 动态注册方法
//  固定格式  只需要换 获取的类
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
    JNIEnv *env = NULL;
    //获取JNIEnv
    if ((*vm)->GetEnv(vm, (void **) &env, JNI_VERSION_1_4) != JNI_OK) {
        return JNI_ERR;
    }
    // 获取类
    jclass cl = (*env)->FindClass(env, "com/xiang/demo/Hello");
    // 注册方法
    if ((*env)->RegisterNatives(env, cl, getMethods,
                                sizeof(getMethods) / sizeof(getMethods[0])) != JNI_OK) {
        return JNI_ERR;
    }
    return JNI_VERSION_1_4;

}







